#include "Grilla.h"

#include <iostream>
#include "malloc.h"
#include "Obstaculo.h"
#include "PositionOutOfBoundException.h"

void Grilla::initilize(int filas, int columnas, std::string obsDefecto){
	this->filas = filas;
	this->columnas = columnas;

	this->casilleros = (Casillero**)malloc(filas*sizeof(Casillero*));

	this->tipoObstaculoPorDefecto = obsDefecto;

	for(int i=0;i<this->filas;i++){
		// Por cada fila reservo la memoria
		this->casilleros[i] = (Casillero*)malloc(columnas*sizeof(Casillero));

		for(int j=0;j<this->columnas;j++){
			this->casilleros[i][j].setPosicion(i,j);
			Casillero* casillero = &this->casilleros[i][j];
			Obstaculo* obs = new Obstaculo(i,j);
			obs->setTipo(this->tipoObstaculoPorDefecto);
			casillero->setContenido(obs);
			this->casilleros[i][j] = (*casillero);
		}
	}
}

Grilla::Grilla(int filas, int columnas, std::string obsDefecto){
	this->initilize(filas,columnas,obsDefecto);

}

Grilla::Grilla(int filas, int columnas){
	this->initilize(filas,columnas,"desconocido");
}

int Grilla::getFilas(){
	
	return this->filas;
}

int Grilla::getColumnas(){
	return this->columnas;
}

string Grilla::getTipoObstaculoPorDefecto(){
	return this->tipoObstaculoPorDefecto;
}

Casillero* Grilla::getCasillero(int fila, int columna){
	
	if(this->esPosicionInvalida(fila,columna)) {
		throw new PositionOutOfBoundException();
	} else {

		return &this->casilleros[fila][columna];
	}
	
}

void Grilla::setCasillero(int fila, int columna, Casillero* casillero){
	
	if(this->esCasilleroInvalido(casillero)) {
		throw new PositionOutOfBoundException();
	} else {
		this->casilleros[fila][columna] = (*casillero);
	}
}

bool Grilla::esCasilleroInvalido(Casillero* casillero){

	if( (casillero->getFila() < 0) || (casillero->getFila() >= this->filas) ){
	
		return true;
	}
	
	if( (casillero->getColumna()< 0) || (casillero->getColumna() >= this->columnas) ){

		return true;
	}
	return false;
}

bool Grilla::esPosicionInvalida(int fila, int columna){

	if( (fila < 0) || (fila >= this->filas) ){

		return true;
	}

	if( (columna < 0) || (columna >= this->columnas) ){

		return true;
	}
	return false;
}

void Grilla::imprimir(){
	for(int i = 0; i < this->filas; i++){
		
		for(int j = 0; j < this->columnas; j++){
			
			Casillero *casillero = this->getCasillero(i,j);
			if(casillero){
				casillero->imprimir();
			}
		}
	}
//			Pantalla::getInstance()->refrescar();
}

void Grilla::imprimir2(){
	
	for(int i = 0; i < this->filas; i++){
		
		for(int j = 0; j < this->columnas; j++){
			
			this->getCasillero(i,j)->imprimir2();
			
		}
		cout<<endl;
	}
}

Grilla::~Grilla(){

	for(int i=0;i<this->filas;i++){
		for(int j=0;j<this->columnas;j++){
			delete this->casilleros[i][j].getContenido();
		}
	}

	for(int i=0;i<this->filas;i++){
		free(this->casilleros[i]);
	}
	free(this->casilleros);
}